#include <stdio.h>
#include <unistd.h>     
#include <sys/types.h>   
#include <sys/sem.h>
#include <sys/ipc.h>
#include <errno.h>      
#include <stdlib.h>     
#include <pthread.h>    
#include <string.h>     

#define err() do { perror("thread5"); exit(EXIT_FAILURE); } while(0)

int semid;
char array[26];

void * invert( void * args)
{
	struct sembuf wait, _main;
	int i;
	wait.sem_num = 1;
	wait.sem_op = -1;
	wait.sem_flg = SEM_UNDO;
	_main.sem_num = 0;
        _main.sem_op = 1;
        _main.sem_flg = SEM_UNDO;
	for(;;)
	{
		if (semop(semid, &wait, 1) == -1) err();
		for(i = 0; i < 26; ++i) array[i] ^= 32;
		if (semop(semid, &_main, 1) == -1) err();
	}
	return NULL;
}

void * reverse( void * args)
{
	char tmp;
	struct sembuf wait, _main;
        int i;
        wait.sem_num = 2;
        wait.sem_op = -1;
        wait.sem_flg = SEM_UNDO;
        _main.sem_num = 0;
        _main.sem_op = 1;
        _main.sem_flg = SEM_UNDO;
	for(;;)
	{
		if (semop(semid, &wait, 1) == -1) err();
		for(i = 0; i < 13; ++i)
		{
			tmp = array[i];
			array[i] = array[25 - i];
			array[25 - i] = tmp;
		}
		if (semop(semid, &_main, 1) == -1) err();
	}
	return NULL;
}

int main(int argc, char *argv[])
{
	int i;
	pthread_t thread_a, thread_b;
	struct sembuf inv, rev, wait;
	unsigned short zero[3] = {0};
	if((semid = semget(7976, 3, 0664 | IPC_CREAT)) < 0) err();
	if(semctl(semid, 0, SETALL, &zero) == -1) err();
	wait.sem_num = 0;
        wait.sem_op = -1;
        wait.sem_flg = SEM_UNDO;
        rev.sem_num = 2;
        rev.sem_op = 1;
        rev.sem_flg = SEM_UNDO;
	inv.sem_num = 1;
        inv.sem_op = 1;
        inv.sem_flg = SEM_UNDO;
	if (pthread_create (&thread_a, NULL,&invert, (void *) NULL) != 0) err();
	if (pthread_create (&thread_b, NULL,&reverse, (void *) NULL) != 0) err();
	for(i = 0; i < 26; ++i) array[i] = 'a' + i;
	for(;;)
	{
		if (semop(semid, &inv, 1) == -1) err();
		if (semop(semid, &wait, 1) == -1) err();
		for(i = 0; i < 26; ++i) putchar(array[i]);
		putchar('\n');
		sleep(1);
		if (semop(semid, &rev, 1) == -1) err();
                if (semop(semid, &wait, 1) == -1) err();
		for(i = 0; i < 26; ++i) putchar(array[i]);
		putchar('\n');
		sleep(1);
	}
	return 0;
}

